package com.hjieli.controller;

import java.io.IOException;
import java.text.NumberFormat;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.resource.HttpResource;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.hjieli.config.security.util.MD5PasswordEncoder;
import com.hjieli.entity.SysUserInfo;
import com.hjieli.entity.SysUserXRole;
import com.hjieli.entity.WeixinUserInfo;
import com.hjieli.service.SysUserInfoService;
import com.hjieli.service.SysUserXRoleService;
import com.hjieli.service.WeixinUserInfoService;

@RestController
public class LoginController {
	
	@Value("${security.oauth2.client.access-token-uri}")
    private String accessTokenUri;

    @Value("${security.oauth2.client.client-id}")
    private String clientId;

    @Value("${security.oauth2.client.client-secret}")
    private String clientSecret;
    
    @Autowired
    private RestTemplate restTemplate;


    @Autowired
    private SysUserInfoService sysUserInfoService;

    @Autowired
    private WeixinUserInfoService weixinUserInfoService;
    
    @Autowired
    private SysUserXRoleService sysUserXRoleService;
    
	@GetMapping("login")
	public ModelAndView login(
			HttpServletRequest request) {
		ModelAndView modelAndView = new ModelAndView("login");
		request.setAttribute("message","");
		request.setAttribute("username", "");
		request.setAttribute("password", "");
		request.setAttribute("verifyCode", "");
		return modelAndView;
		
	}
	@PostMapping("login/error")
	public ModelAndView loginError(
			HttpServletRequest request,
			HttpServletResponse response) {
		response.setCharacterEncoding("utf-8");
		ModelAndView modelAndView = new ModelAndView("login");
		request.setAttribute("message",request.getAttribute("message"));
		request.setAttribute("username", request.getAttribute("username"));
		request.setAttribute("password", request.getAttribute("password"));
		request.setAttribute("verifyCode", "");
		return modelAndView;
		
	}
	
	@PostMapping("login")
	public void doLogin(
			String message,
			String username, 
			String password,
			String verifyCode, 
			@RequestHeader HttpHeaders httpHeaders,
			HttpServletRequest request,
			HttpServletResponse response) throws IOException, ServletException {
		response.setCharacterEncoding("utf-8");
		Map<String,Object> resultMap = new HashMap<String,Object>();
		
		if(verifyCode == null || verifyCode.equals("")) {
			message =  "验证码不能为空";
			request.setAttribute("message", message);
			request.setAttribute("username", username);
			request.setAttribute("password", password);
			request.setAttribute("verifyCode", "");
			request.getRequestDispatcher("/login/error").forward(request, response);
			return;
		}
		
		//判断验证码是否正确
		String sessionVerifyCode = (String) request.getSession().getAttribute("verifyCode");
		if(sessionVerifyCode == null || !sessionVerifyCode.toLowerCase().equals(verifyCode.toLowerCase())) {
			message =  "验证码错误";
			request.setAttribute("message", message);
			request.setAttribute("username", username);
			request.setAttribute("password", password);
			request.setAttribute("verifyCode", "");
			request.getRequestDispatcher("/login/error").forward(request, response);
			return;
		} 
		
		
		// 构造 post的body内容（要post的内容，按需定义）
        MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
        paramsMap.set("grant_type", "password");
        paramsMap.set("username", username);
        paramsMap.set("password",password);
        paramsMap.set("client_id", clientId);
        paramsMap.set("client_secret", clientSecret);
       
        // 使用客户端的请求头,发起请求
        httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        
        // 强制移除 原来的请求头,防止token失效
        httpHeaders.remove(HttpHeaders.AUTHORIZATION);
        
        //构造请求实体和头
        HttpEntity<MultiValueMap<String, String>> httpRequest = new HttpEntity(paramsMap, httpHeaders);
        String authInfo = null;
        try {
            authInfo = restTemplate.postForObject(accessTokenUri, httpRequest, String.class);
            
        } catch (HttpClientErrorException e) {
            if (e.getStatusCode().equals(HttpStatus.BAD_REQUEST)) {
                byte[] bs = e.getResponseBodyAsByteArray();
                String msg = new String(bs, "utf-8");
                JsonElement jsonElement = JsonParser.parseString(msg);
                
                JsonObject tempJsonObject = jsonElement.getAsJsonObject();
            } 
            response.getWriter().print(resultMap);
            
        }
        if(authInfo == null) {
			request.setAttribute("message",  "请联系管理员核查账号是否激活");
			request.setAttribute("username", username);
			request.setAttribute("password", password);
			request.setAttribute("verifyCode", "");
			request.getRequestDispatcher("/login/error").forward(request, response);
			return;
        }
        JsonElement jsonElement = JsonParser.parseString(authInfo);
        JsonObject jsonObject = jsonElement.getAsJsonObject();
        String accessToken = jsonObject.get("access_token").getAsString();
        String refreshToken = jsonObject.get("refresh_token").getAsString();
        
        response.setHeader("Authorization", "bearer " + accessToken);

        //设置token到cookie
        
        
        Cookie tokenCookie = new Cookie("x-token", accessToken);
        tokenCookie.setMaxAge(60 * 60 * 2);

        Cookie refreshTokenCookie = new Cookie("x-refresh-token", refreshToken);
        refreshTokenCookie.setMaxAge(60 * 60 * 2);
        
        response.addCookie(tokenCookie);
        response.addCookie(refreshTokenCookie);
        
        response.sendRedirect("/admin/index");
//		return modelAndView;
	}
	

	/**
	 * 微信登录
	 * @param openId
	 * @return
	 */
	@PostMapping("wxlogin")
	public String wxLogin(@RequestBody Map<String,String> queryParams,
			@RequestHeader HttpHeaders httpHeaders,
			HttpServletRequest request,
			HttpServletResponse response) {
		//判定系统是否有账号，如果没有就模拟注册一个账号
		 
		QueryWrapper<WeixinUserInfo> queryWrapper = new QueryWrapper<WeixinUserInfo>();
		String openId = "";
		if(queryParams.containsKey("openId") && !"".equals(queryParams.get("openId").toString())) {
			openId = queryParams.get("openId").toString();
		}
		queryWrapper.eq("open_id", openId);
		WeixinUserInfo weixinUserInfo = weixinUserInfoService.getOne(queryWrapper);
		
		//添加一个SysUserInfo 和 weixinUserInfo
		SysUserInfo sysUserInfo = null;
		String userId = "";
		if(weixinUserInfo == null) {
			sysUserInfo = new SysUserInfo();
			String account = accountGen();
	        sysUserInfo.setAccount(account);
	        sysUserInfo.setPassword(new MD5PasswordEncoder().encode(account));//设置默认密码
	        sysUserInfo.setWxPassword(new MD5PasswordEncoder().encode(sysUserInfo.getPassword()));
	        sysUserInfo.setIsEnable(1);
			sysUserInfo.setCreateTime(LocalDateTime.now());
			sysUserInfo.setUserName(account);
			sysUserInfoService.save(sysUserInfo);
			userId = sysUserInfo.getId();
			
			//插入 weixinUserInfo
			weixinUserInfo = new WeixinUserInfo();
			weixinUserInfo.setOpenId(openId);
			weixinUserInfo.setUserId(userId);
			weixinUserInfo.setCreateTime(LocalDateTime.now());
			weixinUserInfo.setIsEnable(1);
			weixinUserInfoService.save(weixinUserInfo);
			
			//给设定初始用户权限
			SysUserXRole sysUserXRole = new SysUserXRole();
			sysUserXRole.setRoleId("f721c85ecac38c5862913d75098de630");
			sysUserXRole.setUserId(userId);
			sysUserXRole.setIsEnable(1);
			sysUserXRole.setCreateTime(LocalDateTime.now());
			sysUserXRoleService.save(sysUserXRole);
			
		}else {
			userId = weixinUserInfo.getUserId();
			//获取用户信息
			QueryWrapper<SysUserInfo> sysUserInfoQueryWrapper = new QueryWrapper<SysUserInfo>();
			sysUserInfoQueryWrapper.eq("id", userId).eq("is_enable", 1);
			sysUserInfo = sysUserInfoService.getOne(sysUserInfoQueryWrapper);
		}
	
		
		// 构造 post的body内容（要post的内容，按需定义）
        MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
        paramsMap.set("grant_type", "password");
        paramsMap.set("username", sysUserInfo.getAccount());
        paramsMap.set("password",sysUserInfo.getPassword());
        paramsMap.set("client_id", clientId);
        paramsMap.set("client_secret", clientSecret);
       
        // 使用客户端的请求头,发起请求
        httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        
        // 强制移除 原来的请求头,防止token失效
        httpHeaders.remove(HttpHeaders.AUTHORIZATION);
        
        //构造请求实体和头
        HttpEntity<MultiValueMap<String, String>> httpRequest = new HttpEntity(paramsMap, httpHeaders);
        String authInfo = null;
        try {
            authInfo = restTemplate.postForObject(accessTokenUri, httpRequest, String.class);
            
        } catch (HttpClientErrorException e) {
        	
        }
        if(authInfo != null) {
    		JsonElement jsonElement = JsonParser.parseString(authInfo);
    		JsonObject jsonObject = jsonElement.getAsJsonObject();
    		JsonObject loginObject = new JsonObject();
    		loginObject.addProperty("userId", userId);
    		loginObject.add("loginInfo", jsonObject);
    		
		    String accessToken = jsonObject.get("access_token").getAsString();
	        String refreshToken = jsonObject.get("refresh_token").getAsString();
	        
	        response.setHeader("Authorization", "bearer " + accessToken);

    		
            //设置token到cookie
            Cookie tokenCookie = new Cookie("x-token", accessToken);
            tokenCookie.setMaxAge(60 * 60 * 2);

            Cookie refreshTokenCookie = new Cookie("x-refresh-token", refreshToken);
            refreshTokenCookie.setMaxAge(60 * 60 * 2);
            
            response.addCookie(tokenCookie);
            response.addCookie(refreshTokenCookie);
    		
        	return loginObject.toString();
        }
		
		return "fail";
		
	}
	
	
	//判定系统账号
    public String accountGen() {
    	String account = "";
		//生成
		int sumCount = sysUserInfoService.count();
		int randomNum = new Random().nextInt(9) + 1;
		account = "" + randomNum + sumCount;
		NumberFormat formatter = NumberFormat.getNumberInstance();   
        formatter.setMinimumIntegerDigits(6);   
        formatter.setGroupingUsed(false);
        account = "C" + (new Random().nextInt(9) + 1) +formatter.format(Integer.parseInt(account));
      
    	//先判断是否存在，在生成
    	if(accountIsExsit(account)) {
    		return accountGen();
    	}
    	return account;
    }
    
    public boolean accountIsExsit(String account) {

    	QueryWrapper<SysUserInfo> queryWrapper = new QueryWrapper<SysUserInfo>();
    	queryWrapper.eq("account", account);
    	int num = sysUserInfoService.count(queryWrapper);
    	if(num == 0) {
    		return false;
    	}
    	return true;
    }
}
